package com.pro.dl.dao.impl;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

import com.pro.dl.dao.service.ProfileDao;
import com.pro.dl.exception.AlreadyPresentObject;
import com.pro.dl.exception.StorageException;
import com.pro.dl.pojo.profile.InputField;
import com.pro.dl.pojo.profile.PersonType;
import com.pro.dl.pojo.profile.Profile;
import com.pro.dl.pojo.profile.ProfileData;
import com.pro.dl.pojo.profile.ProfileTemplate;

public class ProfileDaoImpl extends GenericDaoImpl implements ProfileDao {

	static Logger logger = LogManager.getLogger(ProfileDaoImpl.class);

	@Override
	public void createAPersonType(PersonType personType) throws StorageException {
		try {
			createObject(personType);
		} catch (AlreadyPresentObject e) {
			logger.error(
					"PersonType you are trying to create already present {} exception {}",
					personType, e);
		}
	}
	
	@Override
	public void createProfile(Profile profile) throws StorageException {
		try {
			createObject(profile);
		} catch (AlreadyPresentObject e) {
			logger.error(
					"Profile you are trying to create already present {} exception {}",
					profile, e);
		}
	}

	@Override
	public void createInputField(InputField field) throws StorageException {
		try {
			createObject(field);
		} catch (AlreadyPresentObject e) {
			logger.error(
					"InputField you are trying to create already present {} exception {}",
					field, e);
		}
	}

	@Override
	public void createProfileTemplate(ProfileTemplate profileTemplate)
			throws StorageException {
		try {
			createObject(profileTemplate);
		} catch (AlreadyPresentObject e) {
			logger.error(
					"ProfileTemplate you are trying to create already present {} exception {}",
					profileTemplate, e);
		}

	}

	@Override
	public void updateValue(ProfileData profileData) throws StorageException {
		updateObject(profileData);
	}

	@Override
	public void updateValue(List<ProfileData> profileDatas)
			throws StorageException {
		updateObject(profileDatas);
	}

	@Override
	public void createPersonType(PersonType personType)
			throws StorageException, AlreadyPresentObject {
		createObject(personType);
	}

	@Override
	public void updateProfileTemplate(ProfileTemplate profileTemplate)
			throws StorageException {

		updateObject(profileTemplate);

	}

	@Override
	public Profile getProfile(long profileId) throws StorageException {
		return getObjectById(profileId, Profile.class);
	}

	@Override
	public ProfileTemplate getProfileTemplate(long profileTemplateId)
			throws StorageException {
		return getObjectById(profileTemplateId, ProfileTemplate.class);
	}

	@Override
	public List<ProfileTemplate> getProfileTemplates(long profileId) throws StorageException {

		Session session = sessionFactory.getCurrentSession();
		try {
			Profile profile = (Profile)session.get(Profile.class , profileId);
			List<ProfileTemplate> profileTemplates = profile.getProfileTemplates();
			return profileTemplates;
		} catch (Exception e) {	
			throw new StorageException(e);
		} 
	}

	@Override
	public List<InputField> getInputFields(long profileTemplateId) throws StorageException {

		Session session = sessionFactory.getCurrentSession();
		try {
			ProfileTemplate  profileTemplate = (ProfileTemplate)session.get(ProfileTemplate.class, profileTemplateId);
			return profileTemplate.getInputFieldLists();
		} catch (Exception e) {
			throw new StorageException(e);
		}
	}

	@Override
	public List<ProfileData> getProfileData(long personId)
			throws StorageException {
		return searchObjectsByCriteria(Collections
				.singletonList((Criterion) Restrictions.eq("person", personId)), ProfileData.class);
	}

	@Override
	public List<ProfileData> getProfileData(long personId,
			long profileTemplateId) throws StorageException {
		return searchObjectsByCriteria(Arrays.asList((Criterion) Restrictions
				.eq("person", personId), (Criterion) Restrictions.eq(
				"profileTemplate", profileTemplateId)

		), ProfileData.class);
	}

	@Override
	public List<ProfileData> getProfileData(long personId,
			long profileTemplateId, long inputFieldId) throws StorageException {
		return searchObjectsByCriteria(Arrays.asList((Criterion) Restrictions
				.eq("person", personId), (Criterion) Restrictions.eq(
				"profileTemplate", profileTemplateId), (Criterion) Restrictions
				.eq("inputField", inputFieldId)), ProfileData.class);
	}

}
